package dem3;

import javax.xml.soap.Node;

/**
 * Created with Intellij IDEA.
 * Description:
 * User: 33013
 * Date: 2023-04-06
 * Time: 22:05
 */
public class SingleLinkedList {
    private Node head;
    private int size;

    private class Node{
        private int data;
        private Node next;

        public Node(int data) {
            this.data = data;
        }

        public int getData() {
            return data;
        }

        public void setData(int data) {
            this.data = data;
        }

        public Node getNext() {
            return next;
        }

        public void setNext(Node next) {
            this.next = next;
        }
    }

    public Node getHead() {
        return head;
    }

    public int getSize(){
        return size;
    }

    public boolean contains(int value){
        Node cur = head;
        while (cur != null){
            if (cur.getData() == value){
                return true;
            }
            cur = cur.getNext();
        }
        return false;
    }

    public void addLast(int value){
        if(this.head == null){
            head = new Node(value);
        }else {
            Node cur = head;
            while (cur.getNext() != null){
                cur = cur.getNext();
            }
            cur.setNext(new Node(value));
        }
        size++;
    }

    public void addFirst(int value){
        if(this.head == null){
            head = new Node(value);
        }else {
            Node node = new Node(value);
            node.setNext(head);
            head = node;
        }
        size++;
    }

    public void add(int index, int value){
        if (index < 0 || index > size){
            throw new IndexOutBround();
        }
        if (index == 0){
            addFirst(value);
            return;
        }
        if (index == size){
            addLast(value);
            return;
        }
        Node cur = searchPrev(index);
        Node node = new Node(value);
        node.setNext(cur.getNext());
        cur.setNext(node);
        size++;
    }

    private Node searchPrev(int index){
        Node cur = head;
        while (index > 1){
            cur = cur.getNext();
            index--;
        }
        return cur;
    }

    public void removeFirst(){
        if (head == null){
            throw new IndexOutBround("该链表为空");
        }
        head = head.getNext();
        size--;
    }

    public void removeLast(){
        if (head == null){
            throw new IndexOutBround("该链表为空");
        }
        Node prev = searchPrev(size - 1);
        prev.setNext(null);
        size--;
    }

    public void remove(int value){
        if (head == null){
            throw new IndexOutBround("该链表为空");
        }
        Node prev = null;
        if (head.getData() == value){
            removeFirst();
            return;
        }
        prev = findValuePrev(value);
        if (prev == null){
            return;
        }
        prev.setNext(prev.getNext().getNext());
        size--;
    }

    public void removeAll(int value){
        if(head == null){
            return;
        }
        int count = 0;
        Node prev = head;
        Node cur = prev.next;
        while(cur != null){
            if(cur.getData() == value){
                count++;
                cur = cur.getNext();
                if(cur == null){
                    prev.setNext(null);
                }
                continue;
            }
            prev.setNext(cur);
            prev = cur;
            cur = cur.getNext();
        }
        if(head.getData() == value){
            head = head.getNext();
            count++;
        }
        size = size - count;
    }

    private Node findValuePrev(int value){
        Node cur = head;
        while (cur.next != null){
            if (cur.getNext().getData() == value){
                return cur;
            }
        }
        return null;
    }

    public void show(){
        Node cur = head;
        while (cur != null){
            System.out.print(cur.getData());
            System.out.print(" ");
            cur = cur.getNext();
        }
        System.out.println();
    }

    public void clear(){
        size = 0;
        if (head == null){
            return;
        }
        Node prev = head;
        Node cur = prev.getNext();
        while (cur != null){
            prev.setNext(null);
            prev = cur;
            cur = cur.getNext();
        }
        head = null;
        prev = null;
    }

}
